package com.fjasmin.locationutils;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;

import java.io.IOException;
import java.util.List;
import java.util.Locale;

import androidx.core.app.ActivityCompat;

/**
 * @Author qianciling
 * @Date 2021/7/22
 * @Describe 定位工具
 */
public class LocationUtils {
    private static final String TAG = "Utils.Location";

    private volatile static LocationUtils uniqueInstance;
    private final LocationManager locationManager;
    private final Context mContext;
    private AddressCallback addressCallback;

    public void setAddressCallback(AddressCallback addressCallback) {
        this.addressCallback = addressCallback;
    }

    private LocationUtils(Context context) {
        mContext = context;
        locationManager = (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
    }

    public static LocationUtils getInstance(Context context) {
        if (uniqueInstance == null) {
            synchronized (LocationUtils.class) {
                if (uniqueInstance == null) {
                    uniqueInstance = new LocationUtils(context);
                }
            }
        }
        return uniqueInstance;
    }

    /**
     * 获取定位
     */
    public void getLocation() {
        //添加用户权限申请判断
        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "请开启权限");
            localError();
            return;
        }
        List<String> providerList = locationManager.getProviders(true);
        if(providerList.contains(LocationManager.NETWORK_PROVIDER)){
            @SuppressLint("MissingPermission") Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
            if(location != null){
                double latitude = location.getLatitude();//纬度
                double longitude = location.getLongitude();//经度
                if (addressCallback != null) {
                    addressCallback.onGetLocation(latitude, longitude);
                }
                getAddress(latitude, longitude);
            }else{
                localError();
            }
        }else{
            localError();
        }
    }

    private void localError(){
        Log.w(TAG, "定位获取异常");
        if (addressCallback != null) {
            addressCallback.onGetLocation(-1, -1);
        }
    }

    //获取经纬度
    private void showLocation() {

    }

    private void getAddress(double latitude, double longitude) {
        //Geocoder通过经纬度获取具体信息
        Geocoder gc = new Geocoder(mContext, Locale.getDefault());
        try {
            List<Address> locationList = gc.getFromLocation(latitude, longitude, 1);
            if (locationList != null && locationList.size() > 0) {
                if (addressCallback != null) {
                    addressCallback.onGetAddress(locationList.get(0));
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private final LocationListener locationListener = new LocationListener() {
        // Provider的状态在可用、暂时不可用和无服务三个状态直接切换时触发此函数
        @Override
        public void onStatusChanged(String provider, int status, Bundle arg2) {
        }

        // Provider被enable时触发此函数，比如GPS被打开
        @Override
        public void onProviderEnabled(String provider) {
        }

        // Provider被disable时触发此函数，比如GPS被关闭
        @Override
        public void onProviderDisabled(String provider) {
        }

        //当坐标改变时触发此函数，如果Provider传进相同的坐标，它就不会被触发
        @Override
        public void onLocationChanged(Location location) {
            Log.v(TAG, "onLocationChanged>>>" + location.toString());
        }
    };

    public interface AddressCallback {
        void onGetAddress(Address address);

        void onGetLocation(double lat, double lng);
    }
}

